#include "TipsWidget.h"
#include <QPainter>
#include <QApplication>
#include <QRect>
#include <QPropertyAnimation>

TipsWidget::TipsWidget(QString tips, QWidget *sender, DIRECTION dirction, QWidget *parent)
    : QWidget(parent),
      _tips(tips),
      _sender(sender),
      _direction(dirction)
{
    initPara();

    this->resize(_width, _height);
    this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint/* | Qt::Popup*/); // 设置无边框和失去焦点自动关闭，这样设置失去焦点自动关闭会导致圆角有背景，因为有窗口阴影
    this->setAttribute(Qt::WA_TranslucentBackground); // 设置背景透明
    this->installEventFilter(this);

    changePos();
}

void TipsWidget::initPara()
{
    _width = 240;
    _height = 120;
    _radius = 20;
    _textColor = Qt::black;
    _bgColor = QColor(255, 255, 222);
    _font = QFont("微软雅黑", 12);
}

void TipsWidget::changePos()
{
    QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry");
    animation->setDuration(100);

    QPoint point;
    if (_sender)
    {
        int width = _sender->width();
        int height = _sender->height();

        switch (_direction)
        {
        case D_UP:
            {
                // 上边中点
                point = _sender->mapToGlobal(QPoint(width / 2, 0));
                point -= QPoint(_width / 2, MARGIN + _height);
                this->move(point);
            }
            break;
        case D_DOWN:
            {
                // 下边中点
                point = _sender->mapToGlobal(QPoint(width / 2, height));
                point += QPoint(-_width / 2, MARGIN);
                this->move(point);
            }
            break;
        case D_LEFT:
            {
                // 左边中点
                point = _sender->mapToGlobal(QPoint(0, height / 2));
                point -= QPoint(MARGIN + _width, _height / 2);
                this->move(point);
            }
            break;
        case D_RIGHT:
            {
                // 右边中点
                point = _sender->mapToGlobal(QPoint(width, height / 2));
                point += QPoint(MARGIN, -_height / 2);
                this->move(point);
            }
            break;
        }
    }

    QRect startRect, endRect;
    startRect = QRect(point.x() - 50, point.y(), width(), height());
    endRect = QRect(point.x(), point.y(), width(), height());
    animation->setStartValue(startRect);
    animation->setEndValue(endRect);
    animation->start();
}

void TipsWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

#if 0
    // 绘制蒙版模糊的窗口
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(QColor(222, 222, 222/*, 0*/)));
    //painter.setBrush(palette().color(QPalette::Window));

    int arr[10] = { 150, 120, 80, 50, 40, 30, 20, 10, 5, 5 };
    for (int i = 0; i < 10; i++)
    {
        painter.drawRoundedRect(10 - i - 1, 10 - i - 1,
                                _width - (10 - i) * 2, _height - (10 - i) * 2,
                                _radius, _radius);
        painter.setBrush(QBrush(QColor(222, 222, 222, arr[i])));
    }
#else
    // 绘制阴影边框
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    path.addRoundedRect(10, 10, _width - 20, _height - 20, _radius, _radius);

    painter.fillPath(path, QBrush(QColor(255, 255, 222)));

    QColor color(92, 93, 95, 50);
    int arr[10] = { 150, 120, 80, 50, 40, 30, 20, 10, 5, 5 };
    for (int i = 0; i < 10; i++)
    {
        QPainterPath path;
        path.setFillRule(Qt::WindingFill);
        if (i == 5)
            path.addRoundedRect(10 - i - 1, 10 - i - 1,
                                _width - (10 - i) * 2, _height - (10 - i) * 2,
                                _radius, _radius);
        else
            path.addRoundedRect(10 - i - 1, 10 - i - 1,
                                _width - (10 - i) * 2, _height - (10 - i) * 2,
                                _radius, _radius);

        color.setAlpha(arr[i]);
        painter.setPen(color);
        painter.drawPath(path);
    }
#endif

    QRect textRect = rect();
    QPolygon trianglePolygon;
    switch (_direction)
    {
    case D_UP:
        {
            textRect = textRect.marginsRemoved(QMargins(5, 5, 5, 10));
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2 - TRIANGLE_LENGTH, textRect.bottom());
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2 + TRIANGLE_LENGTH, textRect.bottom());
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2, textRect.bottom() + TRIANGLE_LENGTH);
        }
        break;
    case D_DOWN:
        {
            textRect = textRect.marginsRemoved(QMargins(5, 10, 5, 5));
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2 - TRIANGLE_LENGTH, textRect.top());
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2 + TRIANGLE_LENGTH, textRect.top());
            trianglePolygon << QPoint(textRect.left() + textRect.width() / 2, textRect.top() - TRIANGLE_LENGTH);
        }
        break;
    case D_LEFT:
        {
            textRect = textRect.marginsRemoved(QMargins(5, 5, 10, 5));
            trianglePolygon << QPoint(textRect.right(), textRect.top() + textRect.height() / 2 - TRIANGLE_LENGTH);
            trianglePolygon << QPoint(textRect.right(), textRect.top() + textRect.height() / 2 + TRIANGLE_LENGTH);
            trianglePolygon << QPoint(textRect.right() + TRIANGLE_LENGTH, textRect.top() + textRect.height() / 2);
        }
        break;
    case D_RIGHT:
        {
            textRect = textRect.marginsRemoved(QMargins(10, 5, 5, 5));
            trianglePolygon << QPoint(textRect.left(), textRect.top() + textRect.height() / 2 - TRIANGLE_LENGTH);
            trianglePolygon << QPoint(textRect.left(), textRect.top() + textRect.height() / 2 + TRIANGLE_LENGTH);
            trianglePolygon << QPoint(textRect.left() - TRIANGLE_LENGTH, textRect.top() + textRect.height() / 2);
        }
        break;
    }

    painter.setPen(Qt::NoPen);
    painter.setBrush(_bgColor);
    painter.drawRoundedRect(textRect, _radius, _radius);
    painter.drawPolygon(trianglePolygon);

    textRect = textRect.marginsRemoved(QMargins(10, 10, 10, 10));
    painter.setPen(_textColor);
    painter.setFont(_font);
    painter.drawText(textRect, _tips);
}

bool TipsWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::ActivationChange)
    {
        if (QApplication::activeWindow() != this)
        {
            this->close();
        }
    }
    return QWidget::eventFilter(obj, event);
}

void TipsWidget::setText(QString tips)
{
    _tips = tips;
}

void TipsWidget::setDirection(DIRECTION direction)
{
    _direction = direction;
}

void TipsWidget::setSize(int width, int height)
{
    _width = width;
    _height = height;
    this->resize(_width, _height);
    changePos();
}

void TipsWidget::setRadius(int radius)
{
    _radius = radius;
}

void TipsWidget::setTextColor(QColor color)
{
    _textColor = color;
}

void TipsWidget::setBgColor(QColor color)
{
    _bgColor = color;
}

void TipsWidget::setFont(QFont font)
{
    _font = font;
}
